package com.arquitectonic.server.planer;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.ServletContext;

import com.arquitectonic.compartido.Accion;
import com.arquitectonic.compartido.Seccion;

public class Mediador {
	public static Mediador getInstance() {
		if (instancia == null)
			instancia = new Mediador();
		return instancia;
	}

	private static Mediador instancia = null;

	private Mediador() {
	};

	public List<Accion> ejecutarSolver(Collection<Seccion> seccionesPriorizadas,
			int costoIteracion, ServletContext context) {
		escribirProyecto(seccionesPriorizadas, costoIteracion,context);
		ejecutarSolver(context);
		return leerPlan(context);
		
	}

	private String getDirectorio( String nombreArchivo, ServletContext context){
		
		File fileWriter = new File(".");
		fileWriter = new File(fileWriter.getAbsoluteFile().getParent());
		String ruta = fileWriter.getAbsoluteFile().getParent();
		ruta+="\\Planner\\" + nombreArchivo;
		System.out.println("Mostrando ruta:");
		System.out.println(ruta);
		return ruta;
		
	}

	private void escribirProyecto(Collection<Seccion> seccionesPriorizadas,
			int costoIteracion, ServletContext context) {
		// TODO Auto-generated method stub
		try {
			
			String rutaProyecto=getDirectorio("proyecto.plan",context);
			
			BufferedWriter proyecto = new BufferedWriter(new FileWriter(
					rutaProyecto, false));
			proyecto.write("<ActitudSol>\n");
			proyecto.write(" </ActitudSol>\n");
			proyecto.write("<ActitudPlanParc>\n");
			proyecto.write(" </ActitudPlanParc>\n");
			proyecto.write("<RestAgente>\n");
			proyecto.write("constraintP(costoPlan, 10, 100, Plan):-acciones(Plan, Acciones),costoAcciones(Acciones,Costo),costoIteracion(Costoiteracion), Costo > Costoiteracion. costoAcciones([], 0). costoAcciones([A|As], Costo):-costo(A,C1),costoAcciones(As,C2),Costo is C1+C2.costo(action(initial(0),_),0).costo(action(final(0),_),0).costo(action(considerar(Seccion),_),0).costo(action(documentar(Seccion),_), Costo):- costoSeccion(Seccion,Costo).\n");
			for (Seccion s : seccionesPriorizadas)
				proyecto.write("costoSeccion(s_"
						+ s.getNivel().replaceAll("\\.", "_") + ","
						+ s.getCosto() + ").\n");
			proyecto.write("costoSeccion(s_,0).\n");
			proyecto.write("costoIteracion(" + costoIteracion + ").\n");
			proyecto.write("</RestAgente>\n");
			proyecto.write("<ACCIONES>\n");
			proyecto.write("action (documentar(Seccion),[],[not(considerada(Seccion)),not(documentada(Seccion))],[considerada(Seccion),documentada(Seccion)]).action (considerar(Seccion),[],[not(considerada(Seccion))],[considerada(Seccion)]).\n");
			proyecto.write("</ACCIONES>\n");
			proyecto.write("<EstadoMundo>\n");
			proyecto.write(" </EstadoMundo>\n");
			proyecto.write("<EstadoFinal>\n");
			for (Seccion s : seccionesPriorizadas)
				proyecto.write("considerada(s_"
						+ s.getNivel().replaceAll("\\.", "_") + "),\n");
			proyecto.write("considerada(s_)\n");
			proyecto.write("</EstadoFinal>\n");
			proyecto.write("<EstadoInicial>\n");
			for (Seccion s : seccionesPriorizadas)
				if (s.getEstado().equals(Seccion.DONE))
					proyecto.write("considerada(s_"
							+ s.getNivel().replaceAll("\\.", "_") + "),\n");
				else {
					proyecto.write("not(documentada(s_"
							+ s.getNivel().replaceAll("\\.", "_") + ")),\n");
					proyecto.write("not(considerada(s_"
							+ s.getNivel().replaceAll("\\.", "_") + ")),\n");
				}
			proyecto.write("considerada(s_)\n");
			proyecto.write("</EstadoInicial>\n");
			proyecto.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	
	private List<Accion> leerPlan(ServletContext context) {

		LinkedList<Accion> acciones = null;
		try {
			String rutaPlan=getDirectorio("plan.plan",context);
			
			acciones = new LinkedList<Accion>();
			BufferedReader plan = new BufferedReader(new FileReader(rutaPlan));

			plan.readLine();
			for (;;) {
				String accion = plan.readLine();
				if (accion.equals("final(0)"))
					break;
				else {
					if(accion.charAt(0)=='d'){
						accion = accion.substring(14);
						accion = accion.substring(0, accion.indexOf('\''));
						acciones.add(new Accion(accion.replaceAll("_", "\\."),
							"Documentar la seccion " + accion.replaceAll("_", "\\.")));
					}
				}
			}
			plan.close();
			return acciones;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return acciones;
		} catch (IOException e) {
			e.printStackTrace();
			return acciones;
		}

	}

	private void ejecutarSolver(ServletContext context) {

		try {
			String linea;

			String pathPlanner = getDirectorio("Solver.bat",context);

			String envBat =getDirectorio("",context);
				
			File envDir = new File(envBat);
			Process p = Runtime.getRuntime().exec(pathPlanner, null, envDir);

			BufferedReader input = new BufferedReader(new InputStreamReader(
					p.getInputStream()));
			p.waitFor();

			while ((linea = input.readLine()) != null) {
				System.out.println(linea);
			}
			input.close();
		} catch (Exception err) {
			System.out.println("Error ejecutando .bat");
		}

	}

};